from datetime import datetime

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager

from devopsapi.utils.fields import AESCharField

GROUP_TYPE_LIST = [(item, item) for item in ['role', 'project', 'app_type', 'service_type', 'env']]


class UserManager(BaseUserManager):

    def create_user(self, username, email, password=None):
        if username is None:
            raise TypeError('Users must have a username.')

        if email is None:
            raise TypeError('Users must have an emial address')

        user = self.model(username=username, email=self.normalize_email(email))
        user.set_password(password)
        user.save()

        return user

    def create_superuser(self, username, email, password):

        if password is None:
            raise TypeError('Superusers must have a password.')

        user = self.create_user(username, email, password)
        user.is_staff = True

        return user

    def update_password(self, email, password):
        user = self.get(email=email)
        user.set_password(password)
        user.save()
        return user


class User(AbstractBaseUser):
    username = models.CharField(db_index=True, max_length=255, unique=True)
    username_cn = models.CharField(db_index=True, max_length=255, null=True)
    email = models.EmailField(db_index=True, blank=True, null=True, unique=True)
    mobile = models.CharField(max_length=11, unique=True)
    ## 头像这里，需要Pillow模块，pip install Pillow
    icon = models.ImageField(upload_to='icon', default='icon/default.png')
    is_active = models.BooleanField(default=False)
    is_delete = models.BooleanField(default=False)

    projects = models.ManyToManyField(
        'Group',
        blank=True,
        default=None,
        related_name="project_users",
    )

    role = models.ForeignKey(
        'Group',
        related_name='role_users',
        on_delete=models.SET_NULL,
        default=None,
        null=True,
        blank=True,
    )

    public_key = AESCharField(max_length=10240, blank=True, null=True)

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    USERNAME_FIELD = 'username'

    objects = UserManager()

    def __str__(self):
        return self.email

    class Meta:
        db_table = 'devops_user'
        verbose_name = '用户表'
        verbose_name_plural = verbose_name
        ordering = ['-created_at', 'updated_at']


class Group(models.Model):
    name = models.CharField(max_length=128)
    name_cn = models.CharField(max_length=128)
    type = models.CharField(max_length=128, choices=GROUP_TYPE_LIST)
    sudo = models.CharField(max_length=256, blank=True)
    project = models.ForeignKey('Group', on_delete=True, null=True)

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'devops_group'
        verbose_name = '用户组表'
        verbose_name_plural = verbose_name
        ordering = ['-created_at', 'updated_at']


class Captcha(models.Model):
    """注册时验证码"""
    email = models.EmailField(unique=True)
    msg = models.CharField(max_length=128)
    created_at = models.DateTimeField(auto_now=True)
    failed_count = models.IntegerField(default=0)

    def __str__(self):
        return self.email

    class Meta:
        db_table = 'devops_captcha'
        verbose_name = '验证码表'
        verbose_name_plural = verbose_name


class Function(models.Model):
    name = models.CharField(max_length=128)
    parent = models.ForeignKey('self', null=True, on_delete=models.CASCADE)
    path = models.CharField(max_length=128)
    roles = models.ManyToManyField(Group, related_name='functions', blank=True)

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'devops_function'
        verbose_name = '角色函数表'
        verbose_name_plural = verbose_name
